/**
 * Copyright 2019 吉鼎科技.

 * <p>
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * <p>
 * http://www.apache.org/licenses/LICENSE-2.0
 * <p>
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package cn.easyplatform.web.ext.zul;

import cn.easyplatform.web.ext.*;
import org.zkoss.zk.ui.Component;
import org.zkoss.zk.ui.WrongValueException;
import org.zkoss.zk.ui.event.Event;
import org.zkoss.zk.ui.event.EventListener;
import org.zkoss.zk.ui.event.Events;
import org.zkoss.zk.ui.event.ForwardEvent;
import org.zkoss.zk.ui.ext.Disable;
import org.zkoss.zul.Checkbox;
import org.zkoss.zul.Grid;

import java.util.Iterator;

/**
 * @author <a href="mailto:davidchen@epclouds.com">littleDog</a> <br/>
 * @since 2.0.0 <br/>
 */
public class Checkgroup extends Grid implements ZkExt, Reloadable, Assignable,
		Disable, Queryable {

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;

	/**
	 * 查询语句,结果column个数可以有1-3个,当1个的时候value和label共用，2个时分别表示value和label，3个时最后一个是图片
	 */
	private Object _query;

	/**
	 * 数据连接的资源id
	 */
	private String _dbId;

	/**
	 * 在列表中是否要缓存本组件
	 */
	private boolean _cache;

	/**
	 * checkbox的列数
	 */
	private int _cols = 1;

	/**
	 * 保存的格式: [json|array|其它符号，例如逗号，分隔符|等]
	 */
	private String _format = ",";

	/**
	 * 在显示时是否要马上执行查询
	 */
	private boolean _immediate = true;

	/**
	 * 
	 */
	private boolean _disabled;

	/**
	 * 显示类型,default|ios|bs|radio
	 */
	private String _type = "default";

	/**
	 * 如果type等于radio,name不能为空，此时checkgroup变成单选查式，样式成为bs
	 */
	private String _name;

	/**
	 * 当mold = ios或bs有效
	 */
	private String _size;

	/**
	 * 过滤表达式一定存在
	 */
	private String _filter;

	/**
	 * 子项风格
	 */
	private String _itemStyle;
	/**
	 * 是否必需重新加载
	 */
	private boolean _force;

	@Override
	public boolean isForce() {
		return _force;
	}

	public void setForce(boolean force) {
		this._force = force;
	}
	/**
	 * @return the itemStyle
	 */
	public String getItemStyle() {
		return _itemStyle;
	}

	/**
	 * @param itemStyle
	 *            the itemStyle to set
	 */
	public void setItemStyle(String itemStyle) {
		this._itemStyle = itemStyle;
	}

	public String getFilter() {
		return _filter;
	}

	public void setFilter(String filter) {
		this._filter = filter;
	}

	/**
	 * @return
	 */
	public boolean isImmediate() {
		return _immediate;
	}

	/**
	 * @param immediate
	 */
	public void setImmediate(boolean immediate) {
		this._immediate = immediate;
	}

	/**
	 * @return the format
	 */
	public String getFormat() {
		return _format;
	}

	/**
	 * @param format
	 *            the format to set
	 */
	public void setFormat(String format) {
		this._format = format;
	}

	public Object getQuery() {
		return _query;
	}

	public void setQuery(Object query) {
		this._query = query;
	}

	public String getDbId() {
		return _dbId;
	}

	public void setDbId(String dbId) {
		this._dbId = dbId;
	}

	public boolean isCache() {
		return _cache;
	}

	public void setCache(boolean cache) {
		this._cache = cache;
	}

	/**
	 * @return the cols
	 */
	public int getCols() {
		return _cols;
	}

	/**
	 * @param cols
	 *            the cols to set
	 */
	public void setCols(int cols) {
		this._cols = cols;
	}

	@Override
	public void reload() {
		Widget ext = (Widget) getAttribute("$proxy");
		ext.reload(this);
	}

	@Override
	public boolean isDisabled() {
		return _disabled;
	}

	@Override
	public void setDisabled(boolean disabled) {
		if (this._disabled != disabled) {
			Iterator<Component> itr = queryAll("checkbox").iterator();
			while (itr.hasNext()) {
				Checkbox cb = (Checkbox) itr.next();
				cb.setDisabled(disabled);
			}
			this._disabled = disabled;
		}
	}

	@Override
	public void setValue(Object value) {
		Assignable ext = (Assignable) getAttribute("$proxy");
		if (ext != null)
			ext.setValue(value);
	}

	@Override
	public Object getValue() {
		Assignable ext = (Assignable) getAttribute("$proxy");
		if (ext != null)
			return ext.getValue();
		return null;
	}

	public Object getSelectedValue() {
		return getValue();
	}

	public String getLabel() {
		Labelable ext = (Labelable) getAttribute("$proxy");
		if (ext != null)
			return ext.getLabel();
		return null;
	}

	@Override
	public boolean addEventListener(String evtnm,
			EventListener<? extends Event> listener) {
		ForwardEvent e;
		if (evtnm.equals(Events.ON_CHECK)) {
			Iterator<Component> itr = queryAll("checkbox").iterator();
			while (itr.hasNext())
				itr.next().addForward(evtnm, this, evtnm);
			return super.addEventListener(evtnm, listener);
		} else
			return super.addEventListener(evtnm, listener);
	}

	@Override
	public boolean removeEventListener(String evtnm,
			EventListener<? extends Event> listener) {
		if (evtnm.equals(Events.ON_CHECK)) {
			Iterator<Component> itr = queryAll("checkbox").iterator();
			while (itr.hasNext())
				itr.next().removeForward(evtnm, this, evtnm);
			return super.removeEventListener(evtnm, listener);
		} else
			return super.removeEventListener(evtnm, listener);
	}

	public String getType() {
		return _type;
	}

	public void setType(String type) {
		if (type == null)
			type = "default";
		if (!type.equals("default") && !type.equals("switch")
				&& !type.equals("toggle") && !type.equals("tristate"))
			throw new WrongValueException((new StringBuilder())
					.append("type cannot be ").append(type).toString());
		this._type = type;
	}

	public String getSize() {
		return _size;
	}

	public void setSize(String size) {
		if (size == null)
			size = "small";
		if (!size.equals("small") && !size.equals("mini")
				&& !size.equals("normal") && !size.equals("large"))
			throw new WrongValueException((new StringBuilder())
					.append("size cannot be ").append(size).toString());
		this._size = size;
	}

	public String getName() {
		return _name;
	}

	public void setName(String name) {
		this._name = name;
	}

}
